package org.batatasframework.bytecode;

import org.batatasframework.bytecode.spi.AsmLoadable;
import org.batatasframework.bytecode.spi.AsmInstancable;
import org.batatasframework.bytecode.spi.AsmStorable;
import org.springframework.asm.MethodVisitor;

/**
 * 方法体内的本地变量
 * @author jackson
 *
 */
public class LocalVariableAsminfo implements AsmLoadable, AsmStorable, AsmInstancable{
	
	private final AsmMethodBody methodBody;
	private final ClassAsminfo variableType;
	private final int localVariable;
	
	public LocalVariableAsminfo(AsmMethodBody methodBody, ClassAsminfo variableType, int localVariable){
		this.methodBody = methodBody;
		this.variableType = variableType;
		this.localVariable = localVariable;
	}
	
	public AsmMethodBody getMethodBody() {
		return methodBody;
	}
	
	/**
	 * <pre>
	 * 把某一个值赋给这个变量，如：
	 * int i = 0;
	 * 
	 * 注意：这个方法不能单独调用，前面需要有一个值然后才能对这个变量进行赋值
	 * </pre>
	 */
	@Override
	public void store(MethodVisitor visitor){
		visitor.visitVarInsn(variableType.insnStore(), localVariable);
	}
	
	@Override
	public void store(MethodVisitor visitor, AsmLoadable value) {
		value.load(visitor, variableType);
		visitor.visitVarInsn(variableType.insnStore(), localVariable);
	}
	
	@Override
	public void instance(MethodVisitor visitor) {
		variableType.instance(visitor);
		visitor.visitVarInsn(variableType.insnStore(), localVariable);
	}
	
	/**
	 * <pre>
	 * 取值，如：
	 * int i = 1;
	 * ent.setInt(i);
	 * 
	 * 这里就相当于"ent.setInt(i)"里的"i"的取值
	 * </pre>
	 */
	@Override
	public void load(MethodVisitor visitor, ClassAsminfo targetType){
		visitor.visitVarInsn(variableType.insnLoad(), localVariable);
		targetType.cast(visitor, variableType);
	}

	@Override
	public void load(MethodVisitor visitor) {
		visitor.visitVarInsn(variableType.insnLoad(), localVariable);
	}
}
